package day2;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class ChessFrame extends JFrame implements MouseListener {
    int width = Toolkit.getDefaultToolkit().getScreenSize().width;// 获取屏幕宽度和宽度,获取mo'ren
    int height = Toolkit.getDefaultToolkit().getScreenSize().height;
    BufferedImage bgimage = null;//创建缓冲图像
    // 保存棋子的坐标
    int x = 0;
    int y = 0;
    float nx = 0;
    float ny = 0;
    // 保存之前所有下过棋子的坐标,0表示这个点没有棋子,1这个点有黑棋子,2这个点有白棋子
    int[][] allChess = new int[16][16];
    //储存棋子放置的位置
    int[][] chessBoard = new int[2][256];
    //记录棋子的数量
    int qzsl=0;
    // 保存棋子的图片
    //2个棋盘
    int[] lastPiece = new int[2];
    // 表识当前是黑棋还是白棋
    boolean isBlack = true;
    // 标识当前游戏是否可以继续
    boolean canPlay = true;
    String message = "黑方先行";
    // 保存最多拥有多少时间(秒)线程操作
    int maxTime = 0;
    // 做倒计时线程类

    // 保存黑方与白方的剩余时间
    int blackTime = 0;
    int whiteTime = 0;
    // 保存双方剩余时间的信息
    String blackMessage = "无限制";
    String whiteMessage = "无限制";
    @SuppressWarnings("removal")
    public ChessFrame() {
        // 设置标题
        this.setTitle("五子棋");
        // 设置窗口大小
        this.setSize(1080, 850);
        // 设置窗口位置
        this.setLocation((width - 1000) / 2, (height - 1000) / 2);// 设置窗口位置
        // 将窗口设置为大小不改变
        this.setResizable(false);
        // 将窗体的关闭方式设置为默认关闭程序结束
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 为窗体加入监听
        this.addMouseListener(this);
        // 导入图片
        try {
            bgimage = ImageIO.read(getClass().getResource("1.png"));
        }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        this.setVisible(true);//将窗口设置为可见状态，使窗口显示出来

        //刷新屏幕防止开始游戏时无法显示
        this.repaint();//刷新屏幕，确保窗口内容能够正确显示
    }


    public void paint(Graphics g) {
        // 双缓冲技术防止屏幕闪烁
        BufferedImage bi = new BufferedImage(1080, 850, BufferedImage.TYPE_INT_ARGB);
        Graphics g2 = bi.createGraphics();

        // 绘制背景
        g2.drawImage(bgimage, 0, 0, this);
        // 输出标题信息
        g2.setColor(Color.BLACK);
        g2.setFont(new Font("黑体", Font.BOLD, 50));
        g2.drawString("游戏信息:" + message, 70, 90);
        g2.setFont(new Font("宋体", 30, 30));
        g2.setColor(Color.BLACK);
        g2.setFont(new Font("黑体", Font.BOLD, 30));
        g2.drawString("重开游戏", 910, 130);
        g2.drawString("游戏说明", 910, 240);
        g2.drawString("退出游戏", 910, 590);
        g2.drawString("认输", 940, 470);
        g2.drawString("悔棋", 940, 360);
        g2.setColor(Color.CYAN);
        g2.fillOval(900, 650, 150, 100);
        g2.fillOval(880, 640, 50, 50);
        g2.fillOval(1020, 640, 50, 50);
        g2.setColor(Color.BLACK);
        g2.setFont(new Font("宋体", Font.BOLD, 40));
        g2.drawString( "韩凯航", 910, 710);
        g2.setColor(Color.BLACK);
        g2.setFont(new Font("黑体", Font.BOLD, 20));
        // 绘制棋盘
        for (int i = 0; i <= 13; i++) {
            g2.drawLine(150 + i * 50, 125, 150 + i * 50, 775);//循环x轴线
            g2.drawLine(150, 125 + i * 50, 800, 125 + i * 50);//循环y轴线
        }
        // 绘制所有棋子
        for (int i = 1; i <= 14; i++) {
            for (int j = 1; j <= 14; j++) {

                if (allChess[i][j] == 1) {
                    // 黑棋子
                    int tempx = (i - 1) * 50 + 150;
                    int tempy = (j - 1) * 50 + 125;
                    g2.fillOval(tempx - 20, tempy - 20, 40, 40);
                }
                if (allChess[i][j] == 2) {
                    // 白棋子
                    int tempx = (i - 1) * 50 + 150;
                    int tempy = (j - 1) * 50 + 125;
                    g2.setColor(Color.WHITE);
                    g2.fillOval(tempx - 20, tempy - 20, 40, 40);
                    g2.setColor(Color.BLACK);
                    g2.drawOval(tempx - 20, tempy - 20, 40, 40);
                }
            }
        }
        g.drawImage(bi, 0, 0, this);
    }
    // 判断是否有胜利
    @Override
    public void mouseClicked(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override

    public void mousePressed(MouseEvent e) {
        // TODO Auto-generated method stub
        if (canPlay == true) {
            nx = e.getX();
            ny = e.getY();
            if (nx >= 150 && nx <= 800 && ny >= 125 && ny <= 775) {
                x = Math.round((nx - 150) / 50) + 1;
                y = Math.round((ny - 125) / 50) + 1;
                // 判断当前位置是否有棋子
                if (allChess[x][y] == 0) {
                    // 保存上次下棋的位置

                    chessBoard[0][qzsl] = x;
                    chessBoard[1][qzsl] = y;
                    qzsl++;

                    // 判断当前下的是什么颜色的棋子
                    if (isBlack == true) {
                        allChess[x][y] = 1;
                        isBlack = false;
                        message = "轮到白方";
                    } else {
                        allChess[x][y] = 2;
                        isBlack = true;
                        message = "轮到黑方";
                    }
                    // 判断这个棋子是否与其他的棋子连成5个
                    boolean flagwin = this.CheckWin();
                    if (flagwin == true) {
                        JOptionPane.showMessageDialog(this, "游戏结束," + (allChess[x][y] == 1 ? "黑方" : "白方") + "获胜! ");
                        canPlay = false;
                        message = "游戏结束!";
                    }
                } else {
                    JOptionPane.showMessageDialog(this, "当前位置已经有棋子了你不能在下了!");
                }

                this.repaint();
            }

        }
        // 判断鼠标所点击的位置在哪个按钮的区域
        boolean in = this.InRange(900, 85, 1050, 150, e.getX(), e.getY());
        if (in == true) {
            int result = JOptionPane.showConfirmDialog(this, "是否重新开始游戏!");
            // 现在重新开始游戏
            if (result == 0) {
                JOptionPane.showMessageDialog(this, "开始游戏!");
                // 重新开始所要做的操作
                // 1.棋盘清空,把allChess[][]归零;
                for (int i = 1; i <= 14; i++) {
                    for (int j = 1; j <= 14; j++) {
                        allChess[i][j] = 0;
                    }
                }
                canPlay = true;
                // 2.将游戏信息的显示改为初始;
                message = "黑方先行";
                // 3.将下一步下棋的人改为黑方isBlack=true;
                isBlack = true;
                
                // 4.将qzsl归零,chessBoard[][]归零;
                qzsl = 0;
                for (int i = 0; i < 256; i++) {
                    chessBoard[0][i] = 0;
                    chessBoard[1][i] = 0;
                }
                this.repaint();
            }
        } else {
            in = this.InRange(900, 200, 1050, 260, e.getX(), e.getY());
            if (in == true) {
                JOptionPane.showMessageDialog(this, "这是一个五子棋小游戏,黑白双方轮流下棋,当某一方连到五子时游戏结束!");
            } else {
                in = this.InRange(900, 315, 1050, 380, e.getX(), e.getY());
                if (in == true) {
                    {
                        int result = JOptionPane.showConfirmDialog(this, "是否同意对方悔棋？");
                        /**
                         *  悔棋
                         *  1、上次落棋位置置空
                         *  2、调整下次落子颜色与上次一致
                         *  3、调整提示信息
                         *  4、游戏状态设置为已开始
                         */
                        //allChess,chessBoard
                        if (result == 0) {
                            int x_last = lastPiece[0];
                            int y_last = lastPiece[1];
                            int color = allChess[chessBoard[0][qzsl - 1]][chessBoard[1][qzsl - 1]];
                            // 1.上次落棋位置置空
                            allChess[chessBoard[0][qzsl - 1]][chessBoard[1][qzsl - 1]] = 0;
                            qzsl--;
                            if (color == 1) {//若为黑子
                                message = "轮到黑方";
                                isBlack = true;
                            } else {
                                message = "轮到白方";
                                isBlack = false;
                            }
                            //重新绘制棋盘
                            this.repaint();

                            canPlay = true;
                        }
                        //  this.repaint();
                    }
                } else {
                    in = this.InRange(900, 423, 1050, 485, e.getX(), e.getY());
                    if (in == true) {
                        int result = JOptionPane.showConfirmDialog(this, "是否确认认输!");
                        if (result == 0) {
                            JOptionPane.showMessageDialog(this,
                                    (isBlack == true ? "黑方认输," : "白方认输,") + (isBlack == true ? "白方获胜!" : "黑方获胜!"));
                            canPlay = false;
                            this.repaint();
                        }

                    } else {
                        in = this.InRange(900, 540, 1050, 605, e.getX(), e.getY());
                        if (in == true) {
                            JOptionPane.showMessageDialog(this, "退出游戏");
                            System.exit(0);
                        } else {
                            in = this.InRange(900, 670, 1050, 725, e.getX(), e.getY());
                            if (in == true) {
                                String input = JOptionPane.showInputDialog("五子棋五子棋世界上谁最帅？");
                                try {
                                    maxTime = Integer.parseInt(input) * 60;
                                    if (maxTime > 0) {
                                        JOptionPane.showMessageDialog(this, "韩凯航最帅!");
                                    }
                                } finally {

                                }
                                ;
                            }
                        }
                    }
                }
            }
        }
    }

    // 判断区域方法
    private boolean InRange(int x1, int y1, int x2, int y2, int x, int y) {
        boolean In = false;
        if (x >= x1 && x <= x2 && y >= y1 && y <= y2) {
            In = true;
        }
        return In;
    }

    // 判断胜利
    private boolean CheckWin() {
        boolean flag = false;
        // 保存有多少棋子相连
        int count = 1;
        // 判断横向是否有五个棋子相连:特点纵坐标相同,及判断y值相同
        // 通过循环来做判断
        int color = allChess[x][y];
        int i = 1;
        while (color == allChess[x + i][y]) {
            count++;
            i++;
        }
        i = 1;
        while (color == allChess[x - i][y]) {
            count++;
            i++;
        }
        if (count >= 5) {
            flag = true;
        }
        int i2 = 1;
        int count2 = 1;
        while (color == allChess[x][y + i2]) {
            count2++;
            i2++;
        }
        i2 = 1;
        while (color == allChess[x][y - i2]) {
            count2++;
            i2++;
        }
        if (count2 >= 5) {
            flag = true;
        }
        // 斜方向的判断(右上+左下)
        int i3 = 1;
        int count3 = 1;
        while (color == allChess[x + i3][y - i3]) {
            count3++;
            i3++;
        }
        i3 = 1;
        while (color == allChess[x - i3][y + i3]) {
            count3++;
            i3++;
        }
        if (count3 >= 5) {
            flag = true;
        }
        // 斜方向的判断(左上+右下)
        int i4 = 1;
        int count4 = 1;
        while (color == allChess[x + i4][y + i4]) {
            count4++;
            i4++;
        }
        i4 = 1;
        while (color == allChess[x - i4][y - i4]) {
            count4++;
            i4++;
        }
        if (count4 >= 5) {
            flag = true;
        }
        int count1 = 0;
        int color1 = allChess[x][y];
        // 判断横向
        count1 = this.checkCount(1, 0, color1);
        if (count1 >= 5) {
            flag = true;
        } else {
            // 判断纵向
            count1 = this.checkCount(0, 1, color1);
            if (count1 >= 5) {
                flag = true;
            } else {
                // 判断右上,左下
                count1 = this.checkCount(1, -1, color1);
                if (count1 >= 5) {
                    flag = true;
                } else {
                    // 判断右下,左上
                    count1 = this.checkCount(1, 1, color1);
                    if (count1 >= 5) {
                        flag = true;
                    }
                }
            }
        }
        return flag;
    }

    //判断胜利总结的方法避免上方的代码冗余的问题
    private int checkCount(int xChange, int yChange, int color) {
        int count = 1;
        int TempX = xChange;
        int TempY = yChange;
        while (color == allChess[x + xChange][y + yChange]) {
            count++;
            if (xChange != 0) {
                xChange++;
            }
            if (yChange != 0) {
                if (yChange > 0) {
                    yChange++;
                } else {
                    yChange--;
                }
            }
        }
        xChange = TempX;
        yChange = TempY;
        while (color == allChess[x - xChange][y - yChange]) {
            count++;
            if (xChange != 0) {
                xChange++;
            }
            if (yChange != 0) {
                if (yChange > 0) {
                    yChange++;
                } else {
                    yChange--;
                }
            }
        }

        return count;
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub

    }



    @Override
    public void mouseReleased(MouseEvent e) {
        // TODO Auto-generated method stub

    }

}
